package org.tony.common.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.TexturePaint;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.RoundRectangle2D;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.plaf.metal.MetalButtonUI;

import com.sun.awt.AWTUtilities;
/**
 *公共窗体
 */
public class CommonFrame extends JFrame implements MouseListener {

	protected static final long serialVersionUID = 1L;

	protected JPanel containerPanel;
	protected JPanel toolbar;
	protected JPanel titlePanel;

	protected JButton closeButton;
	protected JButton maxButton;
	protected JButton miniButton;


	protected MyMouseAdapter ml;
	protected ActionListener action;
	protected JPanel toolPanel;

	protected ImageIcon normalMaxHilightIcon;
	protected ImageIcon normalMaxIcon;

	protected boolean isMaxmized;
	protected Rectangle normalBounds;


	protected LinkedList<JButton> toolButtons;

	private Map<String, Object> properties;
	private Map<String,String> iconUrls ;
	
	private boolean componetInitial ;
	
	private JPanel content ;

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					// UIManager.setLookAndFeel("org.jvnet.substance.skin.SubstanceOfficeBlue2007LookAndFeel");
					CommonFrame frame = new CommonFrame();
					// /frame.setResizable(false);
					frame.setBounds(100, 100, 800, 600);
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public CommonFrame() {
		initialBasic();
		initialResource();
		normalMaxHilightIcon = this.getImageIcon(CommFrameProps.maxBtnBtnHilightIcon);
		normalMaxIcon = this.getImageIcon(CommFrameProps.maxBtnNormalIcon);
	}

	/**
	 * 初始化资源属性
	 */
	protected void initialResource() {
		iconUrls.put(CommFrameProps.defaultBackgoundImage, "images/bg1.jpg") ;
		iconUrls.put(CommFrameProps.backgroudImage,"images/bg1.jpg") ;
		//iconUrls.put(CommFrameProps.titleIcon, "images/Main_Title.png") ;
		
		iconUrls.put(CommFrameProps.closeBtnClickedIcon,"images/btn_close_down.png");
		iconUrls.put(CommFrameProps.closeBtnNormalIcon,"images/btn_close_normal.png");
		iconUrls.put(CommFrameProps.closeBtnHilightIcon,"images/btn_close_highlight.png");
		
		iconUrls.put(CommFrameProps.minBtnClickedIcon,"images/btn_mini_down.png");
		iconUrls.put(CommFrameProps.minBtnHilightIcon,"images/btn_mini_highlight.png");
		iconUrls.put(CommFrameProps.minBtnNormalIcon,"images/btn_mini_normal.png");

		iconUrls.put(CommFrameProps.maxBtnClickedIcon,"images/btn_max_down.png");
		iconUrls.put(CommFrameProps.maxBtnBtnHilightIcon,"images/btn_max_highlight.png");
		iconUrls.put(CommFrameProps.maxBtnNormalIcon,"images/btn_max_normal.png");

		iconUrls.put(CommFrameProps.restorBtnClickedIcon,"images/btn_restore_down.png");
		iconUrls.put(CommFrameProps.restorBtnBtnHilightIcon,"images/btn_restore_highlight.png");
		iconUrls.put(CommFrameProps.restorBtnNormalIcon,"images/btn_restore_normal.png");
	}
	/**
	 * 初始化基本属性，如窗体装饰、透明、监听器等
	 */
	protected void initialBasic() {
		this.setUndecorated(true);
		//AWTUtilities.setWindowOpaque(this, false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		isMaxmized = false;
		action = new ButtonAction();
		normalBounds = getBounds();
		ml = new MyMouseAdapter();
		toolButtons = new LinkedList<JButton>();
		properties = new HashMap<String, Object>();
		iconUrls = new HashMap<String, String>() ;
		this.addMouseListener(ml);
		this.addMouseMotionListener(ml);
	}

	/**
	 * 初始化右上角工具按钮
	 */
	protected void initalToolButtons() {

		MetalButtonUI tbUI = new MetalButtonUI() ;
		
		toolbar = new JPanel();
		toolbar.setBorder(null);
		toolbar.setOpaque(false);
		FlowLayout fl = new FlowLayout(FlowLayout.RIGHT, 0, 0);
		toolbar.setLayout(fl);

		miniButton = new JButton("");
		miniButton.setUI(tbUI);
		miniButton.setPressedIcon(getImageIcon(CommFrameProps.minBtnClickedIcon));
		miniButton.setIcon(getImageIcon(CommFrameProps.minBtnNormalIcon));
		miniButton.setBorder(null);
		miniButton.setContentAreaFilled(false);
		miniButton.addMouseListener(this);
		miniButton.addActionListener(action);

		toolButtons.addLast(miniButton);

		maxButton = new JButton("");
		maxButton.setUI(tbUI);
		maxButton.setPressedIcon(getImageIcon(CommFrameProps.maxBtnClickedIcon));
		maxButton.setIcon(getImageIcon(CommFrameProps.maxBtnNormalIcon));
		maxButton.setContentAreaFilled(false);
		maxButton.setBorder(null);
		maxButton.addMouseListener(this);
		maxButton.addActionListener(action);
		toolButtons.addLast(maxButton);

		closeButton = new JButton("");
		closeButton.setUI(tbUI);
		closeButton.setPressedIcon(getImageIcon(CommFrameProps.closeBtnClickedIcon));
		closeButton.setIcon(getImageIcon(CommFrameProps.closeBtnNormalIcon));
		closeButton.setBorder(null);
		closeButton.setContentAreaFilled(false);
		closeButton.addMouseListener(this);
		closeButton.addActionListener(action);
		toolButtons.addLast(closeButton);

		for (Iterator<JButton> iter = toolButtons.iterator(); iter.hasNext();) {
			toolbar.add(iter.next());
		}

		toolPanel.add(toolbar, BorderLayout.EAST);
	}

	/**
	 * 组件初始化
	 */
	protected void initialComponent() {

		/**
		 * 创建带有背景图片的容器
		 */
		containerPanel = new JPanel() {
			protected static final long serialVersionUID = 1L;
			
			public void paintComponent(Graphics g) {
				super.paintComponent(g);
			//	ImageIcon backgroud = getImageIcon(CommFrameProps.backgroudImage) ;
				//if (backgroud != null) {
				//	g.drawImage(backgroud.getImage(), 0, 0,null);
					//g2d.fillRoundRect(0, 0, this.getWidth(), this.getHeight(),5, 5);
				//}else {
					TexturePaint paint = CommUiUtil.createTexturePaint(getImageIcon(CommFrameProps.defaultBackgoundImage).getImage());
					Graphics2D g2d = (Graphics2D) g;
					g2d.setPaint(paint);
					g2d.fillRect(0, 0, this.getWidth(), this.getHeight());
				//}

			}
			
		};
		containerPanel.setBorder(new LineBorder(new Color(88,183,237), 1, true));
		setContentPane(containerPanel);
		containerPanel.setLayout(new BorderLayout(0, 0));

		toolPanel = new JPanel();
		toolPanel.setBorder(null);
		toolPanel.setOpaque(false);
		toolPanel.setLayout(new BorderLayout(0, 0));
		toolPanel.setBorder(new EmptyBorder(-5,0,5,0));
		containerPanel.add(toolPanel, BorderLayout.NORTH);

		titlePanel = new JPanel();
		titlePanel.setBorder(new EmptyBorder(0,0,0,0));
		titlePanel.setOpaque(false);
		FlowLayout titleLayout = new FlowLayout(FlowLayout.CENTER, 0, 0);
		titleLayout.setAlignment(FlowLayout.LEFT);
		titlePanel.setLayout(titleLayout);
		if ((getTitle() != null && getTitle().length() > 0)
				|| getImageIcon(CommFrameProps.titleIcon) != null) {
			JLabel titleLab = new JLabel();
			titleLab.setOpaque(false);
			titleLab.setFont(new Font("微软雅黑", Font.BOLD, 14));
			titleLab.setBorder(new EmptyBorder(new Insets(5, 1, 0, 0)));
			titleLab.setText(getTitle());
			if (getImageIcon(CommFrameProps.titleIcon) != null) {
				titleLab.setIcon(getImageIcon(CommFrameProps.titleIcon));
			}
			titlePanel.add(titleLab);
		}
		toolPanel.add(titlePanel, BorderLayout.WEST);

		initalToolButtons();

		if (getBounds() != null && getWidth() > 0 && getHeight() > 0) {
			setBounds(getBounds());
		} else {
			setBounds(100, 100, 416, 300);
		}
		
		if(content!=null) {
			content.setOpaque(false);
			content.setBorder(null);
			containerPanel.add(content,BorderLayout.CENTER);
		}
		this.addComponentListener(new ComponentAdapter() {

            @Override
            public void componentResized(ComponentEvent evt) {
                Shape shape = null;
                shape = new RoundRectangle2D.Float(0, 0, CommonFrame.this.getWidth(),CommonFrame.this.getHeight(), 5, 5);
                AWTUtilities.setWindowShape(CommonFrame.this, shape);
            }
        });
	}

	public void setVisible(boolean bool) {
		if(!componetInitial) {
			initialComponent();
			componetInitial = true ;
		}
		maxButton.setVisible(isResizable());
		super.setVisible(bool);
	}

	public void mouseClicked(MouseEvent e) {
	}

	public void mousePressed(MouseEvent e) {
	}

	public void mouseReleased(MouseEvent e) {
	}

	public void mouseEntered(MouseEvent e) {
		if (e.getSource() == closeButton) {
			closeButton.setIcon(getImageIcon(CommFrameProps.closeBtnHilightIcon));
		} else if (e.getSource() == miniButton) {
			miniButton.setIcon(getImageIcon(CommFrameProps.minBtnHilightIcon));
		} else if (e.getSource() == maxButton && isResizable()) {
			maxButton.setIcon(this.normalMaxHilightIcon);
		}
	}

	public void mouseExited(MouseEvent e) {
		if (e.getSource() == closeButton) {
			closeButton.setIcon(getImageIcon(CommFrameProps.closeBtnNormalIcon));
		} else if (e.getSource() == miniButton) {
			miniButton.setIcon(getImageIcon(CommFrameProps.minBtnNormalIcon));
		} else if (e.getSource() == maxButton && isResizable()) {
			maxButton.setIcon(this.normalMaxIcon);
		}
	}

	protected class MyMouseAdapter extends MouseAdapter {
		protected Point lastScreenPosition;

		public void mousePressed(MouseEvent e) {
			lastScreenPosition = e.getLocationOnScreen();
		}

		public void mouseDragged(MouseEvent e) {
			if (lastScreenPosition != null) {
				Point point = e.getLocationOnScreen();
				int offsetX = point.x - lastScreenPosition.x;
				int offsetY = point.y - lastScreenPosition.y;
				Rectangle bounds = CommonFrame.this.getBounds();
				bounds.x += offsetX;
				bounds.y += offsetY;
				normalBounds = bounds;
				CommonFrame.this.setBounds(bounds);
				lastScreenPosition = point;
			}
		}

	}

	private class ButtonAction implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == closeButton) {
				CommonFrame.this.hanlderCloseEvent();
			} else if (e.getSource() == miniButton) {
				CommonFrame.this.setState(JFrame.ICONIFIED);
			} else if (e.getSource() == maxButton) {
				handlerMaxEvent();
			}

		}

	}

	protected void hanlderCloseEvent() {
		switch (getDefaultCloseOperation()) {
		case JFrame.EXIT_ON_CLOSE:
			System.exit(NORMAL);
			break;
		case JFrame.DISPOSE_ON_CLOSE:
			CommonFrame.this.dispose();
			break;
		default:
			System.exit(NORMAL);
			break;
		}
	}

	private void handlerMaxEvent() {
		if (this.isResizable()) {
			if (this.isMaxmized) {
				this.setBounds(normalBounds);
				this.setExtendedState(JFrame.NORMAL);
				this.isMaxmized = false;
				this.maxButton.setPressedIcon(getImageIcon(CommFrameProps.maxBtnClickedIcon));
				this.maxButton.setIcon(getImageIcon(CommFrameProps.maxBtnNormalIcon));
				this.normalMaxHilightIcon = getImageIcon(CommFrameProps.maxBtnBtnHilightIcon);
				this.normalMaxIcon = getImageIcon(CommFrameProps.maxBtnNormalIcon);
				this.repaint();
				
			} else {
				this.normalBounds = this.getBounds() ;
				Dimension screenSize = Toolkit.getDefaultToolkit()
						.getScreenSize();
				Insets screenInsets = Toolkit.getDefaultToolkit()
						.getScreenInsets(this.getGraphicsConfiguration());
				Rectangle desktopBounds = new Rectangle(screenInsets.left,
						screenInsets.top, screenSize.width - screenInsets.left
								- screenInsets.right, screenSize.height
								- screenInsets.top - screenInsets.bottom);
				this.setMaximizedBounds(desktopBounds);
				this.setExtendedState(JFrame.MAXIMIZED_BOTH);
				this.maxButton.setPressedIcon(getImageIcon(CommFrameProps.restorBtnClickedIcon));
				this.maxButton.setIcon(getImageIcon(CommFrameProps.restorBtnNormalIcon));
				this.normalMaxHilightIcon = getImageIcon(CommFrameProps.restorBtnBtnHilightIcon);
				this.normalMaxIcon = getImageIcon(CommFrameProps.restorBtnNormalIcon);
				this.isMaxmized = true;
			}
		}
	}

	public void addToolButtons(JButton button) {
		button.setBorder(null);
		button.setContentAreaFilled(false);
		toolButtons.add(button);
	}


	public void setTitleIcon(ImageIcon titleIcon) {
		this.properties.put(CommFrameProps.titleIcon, titleIcon) ;
	}
	
	protected ImageIcon getImageIcon(String name) {
		ImageIcon icon = getPropertiy(name, ImageIcon.class) ;
		if(icon == null) {
			String resUrl = iconUrls.get(name) ;
			if(resUrl!=null) {
				icon = getIcon(resUrl) ;
				if(icon != null) {
					properties.put(name, icon);
					return icon ;
				}else {
					return null;
				}
			}
		}
		return icon ;
	}
	
	@SuppressWarnings("unchecked")
	protected <T> T getPropertiy(String name,Class<T> clazz) {
		Object o = properties.get(name) ;
		return o == null ? null : (T)o ;
	}
	
	protected ImageIcon getIcon(String url) {
		URL imageUrl = Thread.currentThread().getContextClassLoader()
				.getResource(url);
		return imageUrl==null?null:new ImageIcon(imageUrl);
	}
	
	public void setBackgroudImage(ImageIcon image) {
		this.putProperties(CommFrameProps.backgroudImage, image) ;
	}
	
	public void putProperties(String keyName,Object value) {
		this.properties.remove(keyName);
		this.properties.put(keyName, value) ;
	}

	public JPanel getContent() {
		return content;
	}

	public void setContent(JPanel content) {
		this.content = content;
	}

}
